#!/usr/bin/env python
# -*- coding: utf-8 -*-

import docutils.core,docutils.nodes,sys,re
from urlparse import urlparse

import sourcecode

marks="#=-_*^>%&|"
lowerroman=['i','ii','iii','iv','v','vi','vii','viii','ix','x','xi']
loweralpha="abcdefghijklmnopqrstuvwxyz"


def gen_rst(node, depth, in_line_block=False):
        global decoration
        #        try:
        #                print "\n------------"
        #                print node.__class__,"::",node.parent.__class__,"::",node.parent.parent.__class__, "::::::::", node,"\n\n"
        #        except:
        #               pass
        
        # Some custom directives save theor source code
        
        try:
            return node.in_rst
        except:
            pass
                
        if isinstance (node, docutils.nodes.document):
                node.rst=gather_rst(node,depth)

        #######################
        ## Tables
        #######################

        elif isinstance (node, docutils.nodes.table):
                node.rst=gather_rst(node,depth)

        elif isinstance (node, docutils.nodes.tgroup):
                rows=[]
                hasHead=False
                for n in node.children:
                        if isinstance (n,docutils.nodes.thead):
                                hasHead=True
                                for row in n.children:
                                        r=[]
                                        for cell in row.children:
                                                r.append(cell)
                                        rows.append(r)
                        elif isinstance (n,docutils.nodes.tbody):
                                for row in n.children:
                                        r=[]
                                        for cell in row.children:
                                                r.append(cell)
                                        rows.append(r)

                filltable (rows)

                heights,widths=calcsizes(rows)

                t=joincells(rows[0],heights[0],widths,topRow=True)
                for i in range (1,len(rows)):
                        if hasHead and i==1:
                                t+=joincells(rows[i],heights[i],widths,belowHead=True)
                        else:
                                t+=joincells(rows[i],heights[i],widths,belowHead=False)

                node.rst=captable(t,top=False,capwith="-")+"\n"

        elif isinstance (node, docutils.nodes.thead):
                node.rst=""

        elif isinstance (node, docutils.nodes.tbody):
                node.rst=""

        elif isinstance (node, docutils.nodes.row):
                 node.rst=""

        elif isinstance (node,docutils.nodes.colspec):
                node.rst=""

        elif isinstance (node,docutils.nodes.entry):
                node.rst=formatcellcontent(gather_rst(node,depth))
        

        #########################
        ## Nodes
        #########################

        elif isinstance (node, docutils.nodes.Text):
                node.rst=node.astext()

        elif isinstance (node, docutils.nodes.strong):
                node.rst="**"+gather_rst(node,depth)+"**"+inlinemarkuptail(node)

        elif isinstance (node, docutils.nodes.emphasis):
                node.rst="*"+gather_rst(node,depth)+"*"+inlinemarkuptail(node)

        elif isinstance (node, docutils.nodes.docinfo):
                node.rst=gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.author):
                if isinstance (node.parent,docutils.nodes.authors):
                        node.rst=gather_rst(node,depth)+"; "
                else:
                        node.rst=":author: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.authors):
                node.rst=":authors: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.organization):
                node.rst=":organization: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.contact):
                node.rst=":contact: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.address):
                node.rst=":address: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.version):
                node.rst=":version: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.status):
                node.rst=":status: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.date):
                node.rst=":date: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.copyright):
                node.rst=":copyright: "+gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.paragraph):
                node.rst=gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.section):
                node.rst=gather_rst(node,depth+1)

        elif isinstance (node, docutils.nodes.title):
                # Special cases: (Not sure this is right ;-)

                if isinstance (node.parent, docutils.nodes.document):
                        t=gather_rst(node,depth)
                        node.rst="="*len(t)+"\n"+t+"\n"+"="*len(t)+"\n\n"
                elif isinstance (node.parent, docutils.nodes.topic):
                        if "abstract" in node.parent.get("classes") or \
                        "dedication" in node.parent.get("classes"):
                                node.rst=""
                        else:
                                node.rst=gather_rst(node,depth)+"\n\n"
                elif isinstance (node.parent, docutils.nodes.admonition) or \
                     isinstance (node.parent, docutils.nodes.sidebar):
                        node.rst=gather_rst(node,depth)+"\n"
                else:
                        t=gather_rst(node, depth)
                        node.rst=t+"\n"+marks[depth]*len(t)+"\n\n"

        elif isinstance (node, docutils.nodes.subtitle):
                if isinstance (node.parent,docutils.nodes.sidebar):
                        node.rst=":subtitle: "+gather_rst(node,depth)+"\n"
                elif isinstance (node.parent,docutils.nodes.document):
                        t=gather_rst(node,depth)
                        node.rst="-"*len(t)+"\n"+t+"\n"+"-"*len(t)+"\n\n"
                else:
                        print "Unknown context for subtitle"
                        print node
                        sys.exit(1)

        elif isinstance (node, docutils.nodes.title_reference):
                node.rst="\ :title:`"+gather_rst(node,depth)+"`\ "

        elif isinstance (node, docutils.nodes.subscript):
                node.rst="\ :subscript:`"+gather_rst(node,depth)+"`\ "

        elif isinstance (node, docutils.nodes.superscript):
                node.rst="\ :superscript:`"+gather_rst(node,depth)+"`\ "

        elif isinstance (node, docutils.nodes.block_quote):
                if "epigraph" in node.get("classes"):
                        node.rst=".. epigraph::\n\n"+indent_text(gather_rst(node, depth),"  ")+"\n"
                elif "highlights" in node.get("classes"):
                        node.rst=".. highlights::\n\n"+indent_text(gather_rst(node, depth),"  ")+"\n"
                elif "pull-quote" in node.get("classes"):
                        node.rst=".. pull-quote::\n\n"+indent_text(gather_rst(node, depth),"  ")+"\n"
                else:
                        node.rst=indent_text(gather_rst(node, depth),"  ")+"\n"

        elif isinstance (node, docutils.nodes.attribution):
                node.rst="--- "+gather_rst(node, depth)+        "\n\n"

        elif isinstance (node, docutils.nodes.literal_block):
                node.rst='::\n\n'+indent_text(gather_rst(node, depth),"  ")+"\n\n"

        elif isinstance (node, docutils.nodes.line_block):
                # FIXME: it doesn't support continuation lines correctly.
                if not in_line_block:
                        ind="| "
                        eol="\n\n"
                else:
                        ind="  "
                        eol="\n"
                node.rst=indent_text(gather_rst(node, depth,in_line_block=True),ind)+eol


        elif isinstance (node, docutils.nodes.doctest_block):
                node.rst=gather_rst(node,depth)+"\n\n"

        elif isinstance (node, docutils.nodes.line):
                node.rst=gather_rst(node, depth)+"\n"

        elif isinstance (node, docutils.nodes.literal):
                node.rst="``"+gather_rst(node, depth)+"``"+inlinemarkuptail(node)

        elif isinstance (node, docutils.nodes.definition_list):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.field_list):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.field):
                node.rst=gather_rst(node, depth)+"\n"

        elif isinstance (node, docutils.nodes.field_name):
                node.rst=":"+gather_rst(node, depth)+":"

        elif isinstance (node, docutils.nodes.field_body):
                node.rst=indent_text (gather_rst(node, depth),"  ")

        elif isinstance (node, docutils.nodes.definition_list_item):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.term):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.classifier):
                node.rst=' : '+ gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.definition):
                node.rst='\n'+indent_text(gather_rst(node, depth),"  ")+'\n'

        elif isinstance (node, docutils.nodes.bullet_list):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.enumerated_list):
                node.rst=gather_rst(node, depth)

        elif isinstance (node, docutils.nodes.list_item):
                if node.parent.get('bullet'):
                        bullet=node.parent.get('bullet')+" "
                        t=indent_text(gather_rst(node,depth)," "*len(bullet))
                        node.rst=bullet+t[len(bullet):]+"\n"

                elif node.parent.get ('enumtype')=='arabic':
                        bullet=node.parent.get('prefix')+\
                        str(node.parent.children.index(node)+1)+\
                        node.parent.get('suffix')+" "
                        t=indent_text(gather_rst(node,depth)," "*len(bullet))

                        node.rst=bullet+t[len(bullet):]+"\n"

                elif node.parent.get ('enumtype')=='lowerroman':

                        bullet=node.parent.get('prefix')+\
                        lowerroman[node.parent.children.index(node)]+\
                        node.parent.get('suffix')+" "
                        t=indent_text(gather_rst(node,depth)," "*len(bullet))

                        node.rst=bullet+t[len(bullet):]+"\n"

                elif node.parent.get ('enumtype')=='upperroman':

                        bullet=node.parent.get('prefix')+\
                        lowerroman[node.parent.children.index(node)].upper()+\
                        node.parent.get('suffix')+" "
                        t=indent_text(gather_rst(node,depth)," "*len(bullet))

                        node.rst=bullet+t[len(bullet):]+"\n"

                elif node.parent.get ('enumtype')=='loweralpha':
                        bullet=node.parent.get('prefix')+\
                        loweralpha[node.parent.children.index(node)]+\
                        node.parent.get('suffix')+" "
                        t=indent_text(gather_rst(node,depth)," "*len(bullet))

                        node.rst=bullet+t[len(bullet):]+"\n"

                else:
                        print "Unknown kind of list_item"
                        print node, node.parent
                        sys.exit(1)
        elif isinstance (node, docutils.nodes.transition):
                node.rst="--------\n\n"

        elif isinstance (node, docutils.nodes.comment):
                node.rst="..\n"+indent_text(gather_rst(node,depth),"   ")+"\n\n"


        elif isinstance (node, docutils.nodes.system_message):
                sys.stderr.write (node.astext()+"\n")
                sys.stderr.flush()
                node.rst=''

        elif isinstance (node, docutils.nodes.footnote):
                if node.get("names") and node.get("auto")==1:
                        node.rst=".. [#"+node.get('ids')[0]+"] "+indent_text(gather_rst(node,depth),"  ")+"\n"
                elif node.get("auto")=="*":
                        node.rst=".. [*] "+indent_text(gather_rst(node,depth),"  ")+"\n"
                else:
                        node.rst=".. ["+node.get('names')[0]+"] "+indent_text(gather_rst(node,depth),"  ")+"\n"

        elif isinstance (node, docutils.nodes.label):
                node.rst=""

        elif isinstance (node, docutils.nodes.footnote_reference):
                if node.get("refid") and (node.get("auto")==1):
                        node.rst="[#"+node.get('refid')+"]_"
                elif node.get("auto")=="*":
                        node.rst="[*]_"
                else:
                        node.rst="["+node.astext()+"]_"

        elif isinstance (node, docutils.nodes.reference):
                #FIXME: maybe de-anonymizing anonymous references is
                #a better idea
                if isinstance (node.parent, docutils.nodes.contact):
                        node.rst=node.astext()
                elif node.get("anonymous")==1:
                        node.rst="`"+node.astext()+"`__"
                elif node.get("refuri"):
                        node.rst="`"+node.astext()+" <"+node.get("refuri")+">`_"
                else:
                        node.rst="`"+node.astext()+"`_"

        elif isinstance (node, docutils.nodes.citation_reference):
                node.rst="["+node.astext()+"]_"

        elif isinstance (node, docutils.nodes.citation):
                node.rst=".. ["+node.next_node(condition=docutils.nodes.label).astext()+"] "+\
                        indent_text(gather_rst(node,depth),"  ")+"\n"

        elif isinstance (node, docutils.nodes.target):
                names=node.get("names")
                if names:
                        if names[0].find(':')==-1:
                                name="`"+names[0]+"`"
                        else:
                                name=names[0]

                refid=node.get("refid")
                refname=node.get("refname")
                #FIXME: maybe de-anonymizing anonymous targets is
                #a better idea
                anon=node.get("anonymous")
                refuri=node.get("refuri")
                if refuri and refuri.endswith("_"):
                        refuri=refuri[:-1]+"\_"

                if anon and refuri:
                        node.rst=".. __: "+refuri+"\n\n"

                elif names and refid and not refuri:
                        node.rst=".. _"+name+": "+refid+"\n\n"

                elif names and not (refuri or refid or refname) :
                        node.rst=".. _"+name+":\n\n"

                elif names and refname:
                        node.rst=".. _"+name+": `"+refname+"`\n\n"

                elif names and refuri:
                        node.rst=".. _"+name+": "+refuri+"\n\n"


                elif refid and not (names or refuri):
                        node.rst=".. _"+node.get("refid")+":\n\n"

                else:
                        print "Don't know how to handle this target"
                        print node

        ###################
        ## Directives
        ###################

        elif isinstance (node, docutils.nodes.attention ):
                t=".. attention::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.caution ):
                t=".. caution::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.danger ):
                t=".. danger::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.error ):
                t=".. error::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.hint ):
                t=".. hint::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.important ):
                t=".. important::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.note ):
                t=".. note::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.tip ):
                t=".. tip::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.warning ):
                t=".. warning::\n"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.admonition ):
                t=".. admonition::"+indent_text(gather_rst(node,depth),"   ")+"\n"
                node.rst=fixdirargs(addclass(node,t))

        elif isinstance (node, docutils.nodes.image):
                if isinstance (node.parent, docutils.nodes.figure):
                        node.rst=" "
                else:
                        node.rst=".. image:: "
                node.rst+=node.get("uri")+"\n"
                for attr in ["alt","height","width", "scale", "align", "target"]:
                        if node.get(attr):
                                node.rst+="   :"+attr+": "+str(node.get(attr))+"\n"
                node.rst=fixdirargs(addclass(node,node.rst))
                node.rst+="\n"

        elif isinstance (node, docutils.nodes.figure):
                t=".. figure:: "+gather_rst(node,depth)
                attrs=""
                if node.get("align"):
                        attrs=attrs+"   :align: "+str(node.get("align"))+"\n"
                if node.get ("classes"):
                        attrs=attrs+"   :figclass: "+str(node.get("classes")[0])+"\n"
                if node.get ("width"):
                        attrs=attrs+"   :figwidth: "+str(node.get("width"))+"\n"
                lines=t.split("\n")
                lines.insert(1,attrs[:-1])
                node.rst='\n'.join(lines)+'\n'

        elif isinstance (node, docutils.nodes.caption):
                node.rst=indent_text(gather_rst(node,depth),"   ")+"\n\n"

        elif isinstance (node, docutils.nodes.legend):
                node.rst=indent_text(gather_rst(node,depth),"   ")+"\n\n"

        elif isinstance (node, docutils.nodes.topic) and \
                "contents" in node.get("classes"):
                node.rst=".. contents::\n\n"

        elif isinstance (node, docutils.nodes.topic) and \
                "dedication" in node.get("classes"):
                node.rst=":dedication:\n"+indent_text(gather_rst(node,depth),"  ")+"\n\n"

        elif isinstance (node, docutils.nodes.topic) and \
                "abstract" in node.get("classes"):
                node.rst=":abstract:\n"+indent_text(gather_rst(node,depth),"  ")+"\n\n"

        elif isinstance (node, docutils.nodes.topic):
                t=".. topic::"+indent_text(gather_rst(node,depth),"   ")
                node.rst=addclass(node,t)+"\n\n"

        elif isinstance (node, docutils.nodes.sidebar):
                t=".. sidebar:: "+indent_text(gather_rst(node,depth),"   ")
                node.rst=fixdirargs(addclass(node,t))+"\n\n"

        elif isinstance (node, docutils.nodes.rubric):
                t=".. rubric:: "+gather_rst(node,depth)
                node.rst=addclass(node,t)+"\n\n"
        
        elif isinstance (node, docutils.nodes.compound):
                t=".. compound::\n\n"+indent_text(gather_rst(node,depth),"   ")
                node.rst=addclass(node,t)+"\n\n"
        
        elif isinstance (node, docutils.nodes.container):
                node.rst=".. container:: "+node.get("classes")[0]+"\n\n"+indent_text(gather_rst(node,depth),"   ")+"\n\n"
        
        elif isinstance (node, docutils.nodes.decoration):
                node.rst=gather_rst(node,depth)
        
        elif isinstance (node, docutils.nodes.header):
                node.rst=""
                decoration += ".. header:: "+indent_text(gather_rst(node,depth),"   ")+"\n\n"
        
        elif isinstance (node, docutils.nodes.footer):
                node.rst=""
                decoration += ".. footer:: "+indent_text(gather_rst(node,depth),"   ")+"\n\n"

        elif isinstance (node, docutils.nodes.substitution_definition):
                node.rst=".. |"+node.get("names")[0]+"| replace::"+indent_text(gather_rst(node,depth),"   ")+"\n\n"

        elif isinstance (node, docutils.nodes.raw):
                node.rst=".. raw:: "+node.get("format")+"\n"
                if node.get("encoding"):
                        node.rst+="   :encoding: "+node.get("encoding")+"\n"
                if node.get("source"):
                        if urlparse(node.get("source"))[0]=="":
                                node.rst+="   :file: "+node.get("source")+"\n\n"
                        else:
                                node.rst+="   :url: "+node.get("source")+"\n\n"
                else:
                        node.rst+=indent_text(gather_rst(node,depth),"   ")

                node.rst=fixdirargs(node.rst)+"\n\n"

        elif isinstance (node, docutils.nodes.inline):
                node.rst="\ :"+node.get("classes")[0]+":`"+gather_rst(node,depth)+"`\ "

        elif isinstance (node, docutils.nodes.pending):
                if node.transform == docutils.transforms.parts.Contents:
                        node.rst="" # I handle it in a topic with contents class
                else:
                        print "Unknown type of pending node"
                        print node
                        sys.exit(1)

        else:
                print "Unkn. node: ", node.__class__
                print node
                #print node.transform
                sys.exit(1)

        return node.rst

def addclass(node,t):
        if node.get ("class"):
                lines=t.split("\n")
                lines.insert(1,"   :class: "+node.get("class")[0])
                t='\n'.join(lines)
        elif node.get("classes"):
                lines=t.split("\n")
                lines.insert(1,"   :class: "+node.get("classes")[0])
                t='\n'.join(lines)
        return t

def fixdirargs(t):
        head=[]
        lines=t.split("\n")
        i=0
        for line in lines[1:]:
                if re.match("   :[^ ]+:",line): #an argument
                        head.append(line)
                        i=i+1
                else:
                        break
        return lines[0]+'\n'+'\n'.join(head)+'\n\n'+'\n'.join(lines[i+1:])


def depth (node):
        if node.parent==None:
                return 0
        else:
                return 1+depth(node.parent)


def indent_text(text,indentation):
        if len (text)>0 and text[-1]=='\n':
                text=text[:-1]
        lines=text.split('\n')
        return indentation+('\n'+indentation).join(lines)
        

def gather_rst(node, depth, in_line_block=False):
        return ''.join([gen_rst(n,depth,in_line_block) for n in node.children])

def inlinemarkuptail(node):
        sibs=node.parent.children
        tail="\\ "
        try:
                nextsib=sibs[sibs.index(node)+1]
                if nextsib.__class__==docutils.nodes.Text \
                        and (nextsib.astext()[0] not in """'")]}>-/:.,;!?\\""" )\
                        and (not nextsib.astext()[0].isspace()):
                        tail="\\ "
        except:
                pass
        return tail


def captable (text,top=True,capwith="-"):
        t=""
        if top:
                line=text[0:text.find("\n")]
        else:
                line=text[text[:-1].rfind("\n")+1:-1]
        for char in line:
                if char in "|+":
                        t+="+"
                else:
                        t+=capwith
        if top:
                return (t+"\n"+text)
        return (text+t+"\n")

def filltable (rows):

        # If there is a multicol cell, we need to insert Continuation Cells
        # to make all rows the same length

        for y in range(0,len( rows)):
                for x in range (0,len(rows[y])):
                        cell=rows[y][x]
                        if isinstance (cell,str):
                                continue
                        if cell.get("morecols"):
                                for i in range(0,cell.get("morecols")):
                                        rows[y].insert(x+1,"H")
                
        for y in range(0,len( rows)):
                for x in range (0,len(rows[y])):
                        cell=rows[y][x]
                        if isinstance (cell,str):
                                continue
                        if cell.get("morerows"):
                                for i in range(0,cell.get("morerows")):
                                        rows[y+i+1].insert(x,"V")

def calcsizes (rows):

        widths=[0]*len(rows[0])

        heights=[0]*len(rows)

        # On each row, we calculate the maximum height of its one-row cells
        for y in range(0,len(rows)):
                for x in range(0,len(rows[y])):
                        cell=rows[y][x]
                        if isinstance (cell,str):
                                continue
                        cell.rst=gen_rst(cell,0)
                        h=len(cell.rst.split("\n"))
                        if h > heights[y]:
                                heights[y]=h


        # On each col, we calculate the maximum width of its one-col cells
        for x in range (0,len(widths)):
                for y in range (0,len(heights)):
                        cell=rows[y][x]
                        if isinstance (cell,str):
                                continue
                        w=cell.rst.find("\n")
                        if w > widths[x]:
                                widths[x]=w

        return heights,widths

def joincells (row, height,widths,belowHead=False,topRow=False):

        lines =[""]*height
        capline=""
        for x in range(0,len(row)):
                cell=row[x]
                i=0
                div="|"
                if belowHead:
                        capper="="
                else:
                        capper="-"
                corner="+"
                if not isinstance (cell,str):
                        cellines=cell.rst.split("\n")
                else:
                        cellines=[]
                        if cell=="H": # Horizontal continuation cell
                                div=" "
                                corner="+"
                        elif cell=="V": # Vertical continuation cell
                                capper=" "
                                corner="+"

                cellines+=[""]*(height-len(cellines))

                capline+=corner+capper*(widths[x])
                if x == len(row)-1:
                        if topRow:
                                capline+="+"
                        else:
                                capline+=corner


                for line in cellines:
                        line = line + " "*(widths[x]-len(line))
                        lines [i]+=div+line
                        i=i+1

        for i in range(0,len(lines)):
                lines[i]=lines[i]+"|"

        text="\n".join(lines)+"\n"

        return capline+"\n"+text

def formatcellcontent (text):
        """Make a neat square piece of text"""
        lines=text.split('\n')
        r=[]
        # Remove extraneous spaces at the right
        for line in lines:
                r.append(line.rstrip())

        # Remove empty first/last lines
        while len(r)>0 and r[0]=="":
                r=r[1:]

        while len(r)>0 and r[-1]=="":
                r=r[:-1]

        # Find max. width
        max=0
        for line in r:
                if len(line) > max:
                        max=len(line)
        # Pad them at the right with spaces, plus
        # one space at each end
        r2=[]
        for line in r:
                r2.append(" "+line+" "*(max-len(line))+" ")

        # Extra empty lines at beginning/end
        r2.insert(0," "*(max+2))
        r2.append(" "*(max+2))

        result= '\n'.join(r2)
        return result

import sys
import pprint
from types import StringType
from docutils import __version__, __version_details__, SettingsSpec
from docutils import frontend, io, utils, readers, writers
from docutils.frontend import OptionParser
from docutils.transforms import Transformer
import docutils.readers.doctree


##class PPublisher( docutils.core.Publisher):
##    def apply_transforms(self):
##        self.document.transformer.populate_from_components(
##            (self.source, self.reader, self.reader.parser, self.writer,
##             self.destination))
##        self.document.transformer.transforms=self.document.transformer.transforms[1:]
##        #print self.document.transformer.transforms
##        self.document.transformer.apply_transforms()

decoration = u""

if __name__ == "__main__":
    input=open(sys.argv[1]).read()
    import docutils.core
    doc=docutils.core.publish_doctree(input)
    print (gen_rst(doc,0)+decoration).encode("utf-8")


